package com.ygqh.baby.service.task;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.model.BalanceDetailForTask;
import com.ygqh.baby.po.YgOrder;
import com.ygqh.baby.po.YgOrderDetail;
import com.ygqh.baby.po.YgReturnOrder;
import com.ygqh.baby.po.YgUserBalanceDetail;
import org.apache.commons.collections4.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

public interface YgBalanceTaskService {
	final static BigDecimal ZERO = new BigDecimal("0.00");
	final static BigDecimal MINUS_ONE = new BigDecimal("-1.00");
	final static Long REWARD_ODID = -1L;

	void preBalanceTask();

	void setPreBalanceDetailList(List<YgUserBalanceDetail> detailList, YgOrder order, RebateType rebateType,
								 OperationType operationType, Long userId, String createBy);

	List<YgUserBalanceDetail> getPreBalanceDetailList(List<BalanceDetailForTask> detailModel,
													  RebateType rebateType, OperationType operationType,
													  Long userId, String createBy, String platformNo);

	List<BalanceDetailForTask> preBalancePretreatment(YgOrder order);

	void preBalanceToBalanceTask();

	void checkBalanceToBalanceTask();

	Message doPreToBalance(Long orderId);

	void affiliateUserReport();

	Message reduceBalance(String returnCode, Long orderId);

	void doPreBalanceTask(List<YgOrder> orderList, List<YgReturnOrder> returnList);

	void sendBalanceMsg(List<YgUserBalanceDetail> detailList, BalanceType balanceType);

	/**
	 * 计算代理每月额外奖励
	 */
	void calculateExtraRewards();

	default BigDecimal getPaidPrice(YgOrder order, Boolean onlyYiigoo) {
		BigDecimal price = ZERO;
		YgOrder ygOrder = this.getOrderSharePrice(order);
		List<YgOrderDetail> orderDetail = ygOrder.getOrderDetail();
		if (onlyYiigoo) {
			orderDetail = orderDetail.stream().filter(d -> d.getSupplierId().equals(1L)).collect(Collectors.toList());
		}
		if (CollectionUtils.isNotEmpty(orderDetail)) {
			price = orderDetail.stream().map(d -> d.getOrderSharePrice()).reduce(price, (a, b) -> a.add(b));
		}
		return price;
	}

	default BigDecimal getReturnPrice(YgOrder order, Boolean onlyYiigoo) {
		YgOrder ygOrder = this.getOrderSharePrice(order);
		List<YgOrderDetail> orderDetail = ygOrder.getOrderDetail();
		BigDecimal returnPrice = new BigDecimal("0.00");
		if (onlyYiigoo) {
			orderDetail = orderDetail.stream().filter(d -> d.getSupplierId().equals(1L)).collect(Collectors.toList());
		}
		for (YgOrderDetail od : orderDetail) {
			returnPrice = returnPrice.add(od.getReturnSharePrice());
		}
		return returnPrice;
	}
	/**
	 * 此操作会丢失零元商品
	 * 
	 * @param order
	 * @return
	 */
	default YgOrder getOrderSharePrice(YgOrder order) {
		List<YgOrderDetail> details = order.getOrderDetail();
		List<YgOrderDetail> collect = details.stream().filter(d -> d.getSalePrice().compareTo(ZERO) > 0)
				.collect(Collectors.toList());

		BigDecimal lastPrice = order.getTotalPrice();
		for (int i = 0; i < collect.size(); i++) {
			YgOrderDetail detail = collect.get(i);
			if (i == collect.size() - 1) {
				detail.setOrderSharePrice(lastPrice);
			} else {
				BigDecimal price = order.getOrderSharePrice(detail.getSalePrice().multiply(new BigDecimal(detail.getQuantity())));
				detail.setOrderSharePrice(price);
				lastPrice = lastPrice.subtract(price);
			}

		}
		order.setOrderDetail(collect);
		return order;
	}

	default YgOrder getProductSharePrice(YgOrder order) {
		List<YgOrderDetail> details = order.getOrderDetail();
		List<YgOrderDetail> collect = details.stream().filter(d -> !PromotionType.ManZeng.equals(d.getPromotionType()))
				.collect(Collectors.toList());
		for (int i = 0; i < collect.size(); i++) {
			YgOrderDetail detail = collect.get(i);
			BigDecimal sharePrice = detail.getSalePrice().multiply(BigDecimal.valueOf(detail.getQuantity()));
			detail.setOrderSharePrice(sharePrice);
		}
		order.setOrderDetail(collect);
		return order;
	}

	/**
	 * 生成代理邀请码
	 */
	void generateInviteCode();

	/**
	 * 统计每月未达到保级要求的用户
	 */
	void notPassCultivationByMonth();

	/**
	 * 拼团失败，退预收入
	 *
	 * @param orderId 订单编号
	 * @param completeCodeList 已完成退款单据编号
	 */
	void doCancelGroupOrder(Long orderId, List<String> completeCodeList);
}
